package org.microsites.domain.dao.eod;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import net.lemnik.eodsql.BaseQuery;
import net.lemnik.eodsql.GeneratedKeys;
import net.lemnik.eodsql.Select;
import net.lemnik.eodsql.TypeMapper;
import net.lemnik.eodsql.Update;

import org.microsites.domain.dao.ServerDAO;
import org.microsites.domain.model.Server;
import org.microsites.util.EodDaoSupport;

public class ServerDAOImpl extends EodDaoSupport implements ServerDAO {
	private Query query;
	
	@Override
	public void create(Server entity) {
		entity.setId(getQuery().create(entity));
	}

	@Override
	public void delete(Long id) {
		getQuery().delete(id);
	}

	@Override
	public List<Server> list() {
		return getQuery().list();
	}

	@Override
	public List<Server> sublist(Long id) {
		return id == null ? new ArrayList<Server>() : getQuery().sublist(id);
	}

	@Override
	public Server load(Long id) {
		return getQuery().load(id);
	}

	@Override
	public void update(Server entity) {
		getQuery().update(entity);
	}
	
	public Query getQuery() {
		if (query == null) {
			query = super.getQuery(Query.class);
			super.addTypeMapper(Server.Type.class, new ServerTypeMapper());
		}
		return query;
	}

	@Override
	public List<String> autocomplete(String column, String pattern) {
		return super.select(String.class, "SELECT " + column + " FROM Server WHERE " + column + " LIKE ?1 GROUP BY " + column, '%' + pattern + '%');
	}

	static interface Query extends BaseQuery {
		
		@Select(sql = "SELECT * FROM Server")
		public List<Server> list();

		@Select(sql = "SELECT * FROM Server WHERE host=?1")
		public List<Server> sublist(Long id);
		
		@Select(sql = "SELECT * FROM Server WHERE id=?1")
		public Server load(Long id);

		@Update(sql = "INSERT INTO Server (type,name,version,description,path,dataPath,service,host,port,admin) " +
        		"VALUES (?{1.type},?{1.name},?{1.version},?{1.description},?{1.path},?{1.dataPath},?{1.service},?{1.host},?{1.port},?{1.admin})",
                keys = GeneratedKeys.RETURNED_KEYS_FIRST_COLUMN)
		public Long create(Server d);
		
		@Update(sql = "UPDATE Server SET type={1.type},name={1.name},version={1.version},description={1.description}," +
				"path={1.path},dataPath={1.dataPath},service={1.service},host={1.host},port={1.port},admin={1.admin}WHERE id=?{1.id}")
		public void update(Server d);
		
		@Update(sql = "DELETE FROM Server WHERE id=?1")
		public void delete(Long id);
	}

	static class ServerTypeMapper implements TypeMapper<Server.Type> {
        public Server.Type get(ResultSet results, int column) throws SQLException {
            return Server.Type.valueOf(results.getString(column));
        }

        public void set(PreparedStatement statement, int column, Server.Type obj) throws SQLException {
            if(obj != null) {
                statement.setString(column, obj.name());
            } else {
                statement.setNull(column, Types.VARCHAR);
            }
        }

        public void set(ResultSet results, int column, Server.Type obj) throws SQLException {
            results.updateString(column, obj.name());
        }
		
	}
	
}
